Informatica Basic: Procedure e Funzioni.
Informatica - Basic: Procedure e funzioni L'Istruzione Sub per la definizione di sottoprogrammi Il richiamo del sottoprogramma La dichiarazione dei sottoprogrammi La scrittura di un programma con subroutine Richiamo di sottoprogrammi in linguaggio macchina Il trasferimento del controllo L'Istruzione common e le variabili globali INFORMATICA - BASIC: PROCEDURE E FUNZIONIL'ISTRUZIONE GOSUBNelle prime versioni del Basic l'unica istruzione disponibile per il richiamo di un sottoprograma era l'istruzione GOSUB.GOSUB numeroRiga numeroRiga è la prima riga del sottoprogramma; il sottoprogramma può essere definito in qualsiasi punto e deve contenere una o più istruzioni RETURN. L'istruzione RETURN indica il rientro dal sottoprogramma; l'esecuzione cioè deve essere ripresa dall'istruzione successiva alla GOSUB che è servita per il richiamo del sottoprogramma. L'istruzione GOSUB è ancora disponibile insieme alla ON... GOSUB che permette di richiamare un diverso sottoprogramma in base al valore di una variabile (analogamente a quanto visto per la ON ... GOTO); è comunque preferibile non usare queste istruzioni e servirsi invece della SUB per la definizione del sottoprogramma e della CALL per il richiamo. L'ISTRUZIONE SUB PER LA DEFINIZIONE DI SOTTOPROGRAMMIIl modo migliore per definire un sottoprogramma è usare l'istruzione SUB.SUB nome [(elencoargomenti)] [STATIC] [bloccoistruzioni] END SUB Nome è il nome del sottoprogramma e non deve avere suffissi; elencoargomenti è un elenco di variabili che rappresentano i parametri formali del sottoprogramma; ogni variabile può essere definita come variabile [()] [AS tipo] le parentesi vanno indicate quando la variabile è di tipo vettoriale; il tipo può essere utilizzato invece dei suffissi; ANY indica che si tratta di un tipo qualsiasi di dati. La parola STATIC serve per richiedere che i valori delle variabili locali vengano salvati tra una chiamata e l'altra del sottoprogramma. IL RICHIAMO DEL SOTTOPROGRAMMAIl sottoprogramma può essere richiamato nei punti in cui è necessario con l'istruzione CALL.[CALL] nome [([elencoargomenti])] Elencoargomenti è una lista di variabili o costanti separate da virgole che rappresenta la lista dei parametri attuali da fornire al sottoprogramma; il valore degli argomenti viene sostituito ordinatamente nelle variabili indicate nella SUB come parametri formali. Il passaggio dei parametri è per indirizzo, cioè ogni modifica ad un parametro formale ha effetto anche sul corrispondente parametro attuale; se si vuole che una variabile indicata nell'elenco dei parametri non venga modificata dal sottoprogramma bisogna racchiuderla tra parentesi. La parola CALL può essere omessa; se è presente i parametri vanno indicati tra parentesi, altrimenti no. LA DICHIARAZIONE DEI SOTTOPROGRAMMII sottoprogrammi vanno dichiarati all'inizio del programma con l'istruzione DECLARE.DECLARE SUB nome [([elencoargomenti])] LA SCRITTURA DI UN PROGRAMMA CON SUBROUTINELe subroutine vanno dichiarate all'inizio del programma con l'istruzione DECLARE. Poi si scrive il programma principale.Usando il QBasic, per scrivere una subroutine si sceglie la voce "Nuova sub" dal menu "Modifica". Sullo schermo viene presentata una nuova finestra di editor, dove è possibile scrivere la definizione della subroutine. Per tornare a visualizzare e modificare il programma principale o una qualsiasi delle subroutine basta scegliere la voce "SUBs" dal menu "Visualizza"; compare l'elenco di tutti i moduli disponibili tra cui scegliere quello desiderato. RICHIAMO DI SOTTOPROGRAMMI IN LINGUAGGIO MACCHINAE' possibile anche richiamare sottoprogrammi scritti in linguaggio macchina. L'istruzione CALL ABSOLUTE trasferisce il controllo ad un sottoprogramma in linguaggio macchina.PROGRAMMA 10 - CALCOLATRICE TASCABILE Questo programma, come il 5, esegue le quattro operazioni aritmetiche a richiesta; permette però di eseguire più operazioni, finché l'utente decide di terminare il programma, ed esegue alcuni controlli che garantiscono il corretto funzionamento anche in caso di errore da parte dell'utente. Il programma è realizzato con il metodo dell'analisi top-down e la codifica è realizzata facendo uso di subroutine. Descrizione delle variabili. La descrizione delle variabili deve essere fatta separatamente per ogni modulo (programma principale e ciascuna subroutine. Programma principale. +----------------------------------------------------------------+ ¦ NOME ¦ TIPO ¦ I/O ¦ SIGNIFICATO ¦ +-----------+-------------+------------------+-------------------¦ ¦ RISPOSTA ¦alfanumerico ¦ input ¦ risposta alla ¦ ¦ ¦ ¦ ¦ domanda di ¦ ¦ ¦ ¦ ¦ continuazione ¦ +----------------------------------------------------------------+Esecuzione operazione. Funzione della subroutine: esegue una operazione; richiesta dati, calcolo, emissione risultato. +----------------------------------------------------------------+ ¦ NOME ¦ TIPO ¦ I/O ¦ SIGNIFICATO ¦ +-----------+-------------+------------------+-------------------¦ ¦ A ¦numero reale ¦ input/output ¦primo operando ¦ ¦ B ¦numero reale ¦ input/output ¦secondo operando ¦ ¦ C ¦numero reale ¦ output ¦risultato ¦ ¦ ¦ ¦ ¦dell'operazione ¦ ¦ OPERATORE ¦alfanumerico ¦ input/output ¦simbolo dell'opera-¦ ¦ ¦ ¦ ¦zione richiesta ¦ ¦ ERRORE ¦ booleano ¦ interno ¦segnale che indica ¦ ¦ ¦ ¦ ¦se si è verificato ¦ ¦ ¦ ¦ ¦un errore ¦ +----------------------------------------------------------------+Divisione. Funzione della subroutine: esegue la divisione tra due numeri, restituendo il risultato della divisione o un segnale di errore se si tenta di eseguire la divisione per zero. +----------------------------------------------------------------+ ¦ NOME ¦ TIPO ¦ I/O ¦ SIGNIFICATO ¦ +-----------+-------------+------------------+-------------------¦ ¦ X ¦ numero reale¦ interno ¦parametro di input;¦ ¦ ¦ ¦ ¦dividendo ¦ ¦ Y ¦ numero reale¦ interno ¦parametro di input ¦ ¦ ¦ ¦ ¦divisore ¦ ¦ Z ¦ numero reale¦ interno ¦parametro di output¦ ¦ ¦ ¦ ¦risultato della ¦ ¦ ¦ ¦ ¦divisione se Y è ¦ ¦ ¦ ¦ ¦diverso da 0 ¦ ¦ ERRORE ¦ booleano ¦ interno ¦parametro di output¦ ¦ ¦ ¦ ¦segnale che indica ¦ ¦ ¦ ¦ ¦il tentativo di ¦ ¦ ¦ ¦ ¦dividere per 0 ¦ +----------------------------------------------------------------+ Guadagnare navigando! Acquisti prodotti e servizi. Guadagnare acquistando online. Flow chart Programma 10 (prima parte)
Flow chart Programma 10 (seconda parte)
Flow chart Programma 10 (terza parte)
Flow chart Programma 10 (quarta parte)
Pseudocodifica (vedi Figure) 1 inizio 2 ripeti 3 esecuzione operazione 4 emissione richiesta di continuazione 5 lettura RISPOSTA 6 finché RISPOSTA = "N" 7 fine 8 Esecuzione operazione 9 ERRORE = falso 10 emissione richiesta primo operando 11 lettura A 12 emissione richiesta secondo operando 13 lettura B 14 ripeti 15 emissione richiesta operatore 16 lettura OPERATORE 17 finché OPERATORE = "+" o "-" o "*" o "/" 18 se OPERATORE = "+" allora 19 C = A + B 20 fine se 21 se OPERATORE = "-" allora 22 C = A - B 23 fine se 24 se OPERATORE = "*" allora 25 C = A * B 26 fine se 27 se OPERATORE = "/" allora 28 divisione(A, B, C, ERRORE) 29 fine se 30 se ERRORE = falso allora 31 emissione A OPERATORE B "=" C 32 altrimenti 33 emissione messaggio di errore 34 fine se 35 fine procedura 36 Divisione(X, Y, Z, ERRORE) 37 se Y > 0 allora 38 Z = X / Y 39 altrimenti 40 ERRORE = vero 41 fine se 42 fine procedura da 1 a 7 Questo è il programma principale; è costituito da un ciclo until che ripete l'esecuzione di una operazione finché l'utente risponde con il carattere N alla richiesta di continuazione. Soltanto il carattere N fa uscire dal programma; qualsiasi altro carattere, anche n minuscolo, fa eseguire un'altra operazione. 3 Chiamata della procedura che svolge in dettaglio l'esecuzione di un'operazione; non viene passata nessuna variabile alla procedura e non si aspetta nessuna variabile di ritorno; la procedura non ha parametri. da 8 a 35 Procedura che svolge l'esecuzione di un'operazione. 9 La variabile ERRORE è una variabile booleana, cioè può assumere soltanto i valori vero o falso; inizialmente viene posta uguale a falso e il suo valore verrà modificato in vero soltanto se si verifica un errore. da 10 a 13 Inserimento degli operandi; si tratta di numeri reali. da 14 a 17 Inserimento del simbolo di operazione; i simboli ammessi sono + - * e /. Il ciclo serve a controllare che si inserisca un valore corretto; se si inserisce un carattere diverso dai simboli ammessi, non viene considerato e si ripete la richiesta del simbolo di operazione. 17 La condizione di uscita dal ciclo until è una condizione composta con degli operatori OR; la condizione composta è falsa se tutte le condizioni semplici sono false ed è vera se almeno una delle condizioni semplici è vera. Se si fosse usato un ciclo while per invertire la condizione si sarebbe dovuto scrivere: OPERATORE = " " mentre OPERATORE diverso da "+" e diverso da "-" e diverso da "*" e diverso da "/" emissione richiesta operatore lettura OPERATORE fine mentre quindi usando l'operatore and invece dell'operatore or; infatti la condizione composta deve essere vera quando tutte le condizioni semplici sono vere e deve diventare falsa appena una delle condizioni semplici diventa vera. da 18 a 29 Esecuzione di una delle operazioni in base al simbolo immesso. 28 Se l'operazione richiesta è una divisione, invece di eseguire direttamente l'operazione come negli altri casi viene richiamata ua procedura che controlla anche se si verifica un errore a causa di un tentativo di dividere per zero. Alla procedura vengono fornite le variabili A e B (dividendo e divisore) e ci si attende di ricevere la variabile C, risultato dell'operazione e la variabile ERRORE che, se ha valore "vero" segnala che il divisore era zero e che non è stato possibile eseguire l'operazione richiesta. 30 Viene esaminato il valore della variabile ERRORE restituita dalla procedura Divisione. Se il valore è falso vuol dire che non si sono verificati errori e ha senso stampare il risultato (riga 31); in caso contrario viene stampato il messaggio di errore (riga 33). 35 Fine della procedura di esecuzione dell'operazione; l'esecuzione del programma prosegue dalla riga 4 del programma principale. da 36 a 42 Procedura che controlla se il divisore è zero e se possibile esegue la divisione. La procedura ha come parametri: X, a cui il modulo chiamante passa il dividendo; Y, a cui il modulo chiamante passa il divisore; Z, in cui la procedura memorizza il risultato, se possibile, e lo restituisce al modulo chiamante; ERRORE (che anche se ha lo stesso nome di una variabile della procedura Esecuzione operazione è in realtà una variabile diversa), a cui il modulo chiamante fornisce il valore falso, e in cui viene posto il valore vero se il divisore è zero. Il valore contenuto in ERRORE viene poi restituito al modulo chiamante. 42 Fine della procedura di divisione. L'esecuzione prosegue dalla riga 29 della procedura Esecuzione operazione. Programma in Basic.10 REM Calcolatrice tascabile 20 DECLARE SUB OPERAZIONE () 30 DECLARE SUB DIVISIONE (X, Y, Z, ERRORE%) 40 REM Programma principale 50 DO 60 OPERAZIONE 70 PRINT "Ancora operazioni?" 80 INPUT RISPOSTA$ 90 LOOP UNTIL RISPOSTA$ = "N" 100 END 110 SUB DIVISIONE (X, Y, Z, ERRORE%) 120 IF Y > 0 THEN 130 Z = X / Y 140 ELSE 150 ERRORE% = 1 160 END IF 170 END SUB 180 SUB OPERAZIONE 190 ERRORE% = 0 200 PRINT "Inserire il primo operando" 210 INPUT A 220 PRINT "Inserire il secondo operando" 230 INPUT B 240 DO 250 PRINT "Inserire il simbolo di operazione" 260 INPUT OPERATORE$ 270 LOOP UNTIL OPERATORE$ = "+" OR OPERATORE$ = "-" OR OPERATORE$ = "*" OR OPERATORE$ = "/" 280 IF OPERATORE$ = "+" THEN 290 C = A + B 300 END IF 310 IF OPERATORE$ = "-" THEN 320 C = A - B 330 END IF 340 IF OPERATORE$ = "*" THEN 350 C = A * B 360 END IF 370 IF OPERATORE$ = "/" THEN 380 DIVISIONE (A), (B), C, ERRORE% 390 END IF 400 IF ERRORE% = 0 THEN 410 PRINT A; " "; OPERATORE$; " "; B; = "; C 420 ELSE 430 PRINT "Impossibile dividere per 0" 440 END IF 450 END SUB20 Dichiarazione relativa alla subroutine OPERAZIONE; il nome è seguito dalle parentesi tonde aperta e chiusa perché la subroutine non ha parametri. 30 Dichiarazione relativa alla subroutine DIVISIONE; il nome della procedura è seguito dai parametri tra parentesi. da 40 a 100 Codifica del programma principale. Nel programma principale è possibile richiamare le procedure, anche se non sono ancora state definite, perché comunque sono state dichiarate nelle righe precedenti. 60 Richiamo della subroutine OPERAZIONE; per richiamare la subroutine basta indicare il nome. da 110 a 170 Definizione della subroutine DIVISIONE. 110 La subroutine è definita con la parola SUB, il nome, con cui può essere richiamata, e l'elenco dei parametri tra parentesi. 170 Ogni subroutine termina con l'istruzione END SUB. da 180 a 450 Definizione della procedura OPERAZIONE. 180 Nella definizione della subroutine dopo SUB viene scritto solo il nome poiché la procedura non ha parametri; non vanno messe neanche le parentesi come nella dichiarazione. 190 La variabile ERRORE che logicamente è una variabile booleana viene codificata come numero intero poiché in Basic non esiste una definizione per le variabuli booleane. Basta stabilire che alla variabile possano essere assegnati due soli valori: per esempio 0 per falso e 1 per vero. Infatti viene posta inizialmente a 0 e diventa uguale a 1 soltanto se si tenta di eseguire la divisione per 0 (riga 150 della subroutine DIVISIONE). 380 Richiamo della subroutine Divisione; dopo il nome vengono indicati i
parametri; i parametri A e B sono tra parentesi perché vengono passati come
input alla subroutine ma non devono essere modificati e restituiti dalla
subroutine stessa. +----------------------------------------------------------------+ ¦ Esempi di esecuzione ¦ ¦ ¦ ¦ Inserire il primo operando ¦ ¦ ? 153 ¦ ¦ Inserire il secondo operando ¦ ¦ ? 86 ¦ ¦ Inserire il simbolo di operazione ¦ ¦ ? - ¦ ¦ 153 - 86 = 67 ¦ ¦ Ancora operazioni? ¦ ¦ ? S ¦ ¦ Inserire il primo operando ¦ ¦ ? 98 ¦ ¦ Inserire il secondo operando ¦ ¦ ? 3 ¦ ¦ Inserire il simbolo di operazione ¦ ¦ ? * ¦ ¦ 98 * 3 = 294 ¦ ¦ Ancora operazioni? ¦ ¦ ? S ¦ ¦ Inserire il primo operando ¦ ¦ ? 155 ¦ ¦ Inserire il secondo operando ¦ ¦ ? 5 ¦ ¦ Inserire il simbolo di operazione ¦ ¦ ? / ¦ ¦ 155 / 5 = 31 ¦ ¦ Ancora operazioni? ¦ ¦ ? N ¦ +----------------------------------------------------------------+Commenti E' facile aggiungere alla calcolatrice altre operazioni. Si può provare per esempio ad aggiungere l'elevamento a potenza, fornendo la base e l'esponente. Si potrà allora realizzare una procedura per il calcolo della potenza che restituisca il valore calcolato o una variabile ERRORE in caso di richiesta di operazioni non eseguibili. LE FUNZIONIQuando il sottoprogramma deve restituire un unico valore è possibile definire una funzione che permetta di calcolare tale valore.Non è però mai indispensabile usare una funzione; è sempre possibile usare un sottoprogramma in ogni caso. La definizione di una funzione può essere fatta con l'istruzione DEF FN. nome DEF FN [(elencoparametri)] = espressione nome DEF FN [(elencoparametri)] [bloccoistruzioni] nomeFN=espressione [bloccoistruzioni] END DEF Il nome deve essere un nome di variabile valido; rappresenta il valore che verrà restituito dalla funzione e deve essere definito del tipo desiderato tramite il suffisso o gli altri metodi di specificazione delle variabili. L'elencoparametri rappresenta la lista delle variabili da utilizzare come parametri formali che al momento del richiamo della funzione riceveranno i valori forniti con i parametri attuali. Il richiamo della funzione viene fatto attraverso il nome della funzione seguito dall'elenco dei parametri attuali. Il primo formato dell'istruzione DEF FN viene utilizzato quando la definizione della funzione può essere descritta con una semplice istruzione; il secondo formato quando la definizione è più complessa; deve comunque essere presente un'istruzione che assegni il valore risultato della funzione alla variabile che rappresenta il nome della funzione stessa. Per definire una funzione è possibile usare anche l'istruzione FUNCTION. FUNCTION nome [(elencoparamteri)] [STATIC] [bloccoistruzioni] nome=espressione [bloccoistruzioni] END FUNCTION anche qui il nome deve essere un nome di variabile valido, con la specificazione del tipo di dato. Se viene specificata la parola STATIC i valori delle variabili locali vengono salvati tra una chiamata e l'altra della funzione. Le funzioni definite con l'istruzione FUNCTION vanno dichiarate all'inizio del programma con l'istruzione DECLARE. DECLARE FUNCTION nome [([elencoargomenti])] PROGRAMMA 11 - IL MASSIMO TRA DUE NUMERI Questo programma non fa un lavoro molto significativo: calcola soltanto il massimo tra due numeri; lo scopo è quello di dimostrare come sia possibile definire una funzione che compia un lavoro stabilito dall'utente. Descrizione delle variabili. Programma principale. +----------------------------------------------------------------+ ¦ NOME ¦ TIPO ¦ I/O ¦ SIGNIFICATO ¦ +-----------+-------------+------------------+-------------------¦ ¦ A ¦numero reale ¦ input ¦ primo numero da ¦ ¦ ¦ ¦ ¦ confrontare ¦ ¦ B ¦numero reale ¦ input ¦ secondo numero da ¦ ¦ ¦ ¦ ¦ confrontare ¦ +----------------------------------------------------------------+Funzione MASSIMO. Scopo della funzione: calcola il massimo tra due numeri. +----------------------------------------------------------------+ ¦ NOME ¦ TIPO ¦ I/O ¦ PARAMETRI ¦ SIGNIFICATO ¦ +-----------+-------------+-------+----------------+-------------¦ ¦ X ¦numero reale ¦ inter.¦ parametro ¦ primo ¦ ¦ ¦ ¦ ¦ di input ¦ numero da ¦ ¦ ¦ ¦ ¦ ¦ confrontare ¦ ¦ Y ¦numero reale ¦ inter.¦ parametro ¦ secondo ¦ ¦ ¦ ¦ ¦ di input ¦ numero da ¦ ¦ ¦ ¦ ¦ ¦ confrontare ¦ ¦ MASSIMO ¦numero reale ¦ inter.¦ valore ¦ valore ¦ ¦ ¦ ¦ ¦ in output ¦ massimo ¦ +----------------------------------------------------------------+ Flow chart Programma 11 (prima parte)
Flow chart Programma 11 (seconda parte)
Pseudocodifica (vedi Figure) 1 inizio 2 emissione richiesta primo valore 3 lettura A 4 emissione richiesta secondo valore 5 lettura B 6 emissione massimo(A, B) 7 fine 8 massimo(X, Y) 9 se X > Y allora 10 massimo = X 11 altrimenti 12 massimo = Y 13 fine se 14 fine funzioneda 1 a 7 Programma principale che richiede due valori e richiama la funzione per la determinazione del massimo. da 2 a 5 Immissione dei due valori da confrontare. 6 Richiamo della funzione; vengono passati come parametri i due valori da confrontare, A e B; il risultato della funzione viene sostituito al richiamo stesso della funzione; il valore maggiore tra A e B compare cioè al posto di massimo(A, B). da 8 a 14 Definizione della funzione per la determinazione del massimo tra due valori. 8 Al nome della funzione seguono i parametri su cui la funzione lavora, che vengono sostituiti dai valori A e B al momento del richiamo della funzione stessa. da 9 a 13 Struttura condizionale per il confronto tra A e B e la determinazione del maggiore dei due. 10 e 12 Il nome della funzione è una variabile dove viene memorizzato il risultato della funzione. Programma in Basic. 10 REM Calcolo del massimo di due numeri 20 Il nome della funzione è preceduto da DEF FN e seguito dalla lista dei parametri, tra parentesi. 40 Il risultato viene memorizzato nella variabile identificata dal nome della funzione preceduto da FN. 80 Le funzioni terminano con l'istruzione END DEF. da 90 a 150 Programma principale. 140 Richiamo della funzione; la funzione viene richiamata con il nome preceduto da FN e seguito dalla lista dei parametri tra parentesi. +------------------------------ Una funzione non è mai indispensabile, può sempre essere sostituita da una subroutine; per esempio in questo caso è possibile sostituire la funzione MASSIMO con la subroutine max(X, Y, MASSIMO) se X > Y allora massimo = X altrimenti massimo = Y fine se fine proceduradove X e Y sono parametri di input e MASSIMO è il parametro di output. IL TRASFERIMENTO DEL CONTROLLOAltre istruzioni per il trasferimento del controllo sono RUN e CHAIN.L'istruzione RUN permette di avviare l'esecuzione di un programma, specificando eventualmente il punto del programma da cui partire. RUN [{numeroriga|file$] numeroriga è la riga da cui partire del programma corrente; file$ invece è il nome di un file contenente un programma sorgente in Basic da eseguire; prima di avviare l'esecuzione questa istruzione chiude i file che al momento si trovano aperti e libera la memoria. L'istruzione CHAIN invece permette di trasferire il controllo ad un altro programma ma senza chiudere i file aperti. CHAIN file$ File$ contiene il nome del programma da eseguire. L'ISTRUZIONE COMMON E LE VARIABILI GLOBALILe variabili definite in un modulo (sottoprogramma o funzione) sono locali a quel modulo, cioè sono definite soltanto all'interno del modulo stesso e non sono utilizzabili all'esterno.L'istruzione COMMON permette di definire variabili globali, cioè comuni a tutto il programma. Dizionario Basic.(s.m. ingl.) sigla di Beginner's All-purpose Symbolic Instruction Code: codice d'istruzione simbolico-polivalente per principianti. Nome di un linguaggio di programmazione molto diffuso perché di facile applicazione.Inglese BasicFrancese BasicTedesco BasicMicrosoft.(s.f.), nome di un'azienda statunitense specializzata nel software di base. Ha al suo attivo molti prodotti di larghissima diffusione, quali il sistema operativo MS-DOS e varie versioni di Basic.Inglese MicrosoftFrancese MicrosoftTedesco MicrosoftEnciclopedia termini lemmi con iniziale a b c d e f g h i j k l m n o p q r s t u v w x y z Storia Antica dizionario lemmi a b c d e f g h i j k l m n o p q r s t u v w x y z Dizionario di Storia Moderna e Contemporanea a b c d e f g h i j k l m n o p q r s t u v w y z Lemmi Storia Antica Lemmi Storia Moderna e Contemporanea Dizionario Egizio Dizionario di storia antica e medievale Prima Seconda Terza Parte Storia Antica e Medievale Storia Moderna e Contemporanea Dizionario di matematica iniziale: a b c d e f g i k l m n o p q r s t u v z Dizionario faunistico df1 df2 df3 df4 df5 df6 df7 df8 df9 Dizionario di botanica a b c d e f g h i l m n o p q r s t u v z |
Buon Giorno! ::::: Grazie per la visita! |
![]() |
Copyright (c) 2002 - 15 Mag. 2025 6:19:23 am trapaninfo.it home disclaim |
Ultima modifica : 02/01/2025 18:43:39